﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ManagementEffect;
using Yugi.Client.Card;
using System.Threading;
using ServerYuGi.PythonRegister;

namespace ServerYuGi.ChainEffectManager
{
    public partial class ChainManager
    {
        SSupervisor super;
        List<ItemChain> ListChainNow;
        public Queue<ItemMultiChain> QueueMultiChain;
        public bool isActiveChain = false;
        public bool isExcuting = false;
        
    

        public ChainManager(SSupervisor super)
        {
            this.super = super;
            ListChainNow = new List<ItemChain>();
            QueueMultiChain = new Queue<ItemMultiChain>();
        }
        public void F5()
        {
            Init();
            isExcuting = false;
            QueueMultiChain.Clear();
        }
        public void Init()
        {
            ListChainNow.Clear();
            isExcuting = false;
        }
        public void AddChain(List<YCheckPoint> Listcheckpoint,int IDCard,int CardTypeID,int Speed)
        {
            for (int i = 0; i < Listcheckpoint.Count;i++ )
            {
                YCheckPoint checkpoint = Listcheckpoint[i];
                string scriptExcute = super.EffectTurnManager.GetScriptExecute(checkpoint, IDCard);
                if (!CheckItemInListChain(IDCard))
                    continue;
                ListChainNow.Add(new ItemChain(checkpoint, IDCard, CardTypeID, Speed,scriptExcute));
                Console.WriteLine("***Chain: List Chain Add Phan Tu Dau Tien"); 
            }
                          
        }

        public void AddItemMultiChain(YCheckPoint Checkpoint, int idPlayer, int CardTypeID, int idCard)
        {
            CardScript script = super.CScriptDB.GetScript(CardTypeID);
            if (script != null && !script.Check_Register_Script.Equals(""))
                super.pyregister.AddStore(script.GetListCheckPoint(), idCard);

            ItemMultiChain item = new ItemMultiChain
            {
                checkpoint = Checkpoint,
                IDPlayerCheck = idPlayer,
                names = "api_manager",
                values = new object[] { super.api_manager }
            };
            QueueMultiChain.Enqueue(item);
            Console.WriteLine("Add multi chain CheckPoint=" + Checkpoint.ToString());
            CheckMultiChain();
        }
        public void AddItemMultiChain(YCheckPoint Checkpoint, int idPlayer, int CardTypeID, int idCard,string var_name,object[] var_value)
        {
            CardScript script = super.CScriptDB.GetScript(CardTypeID);
            if (script != null && !script.Check_Register_Script.Equals(""))
                super.pyregister.AddStore(script.GetListCheckPoint(), idCard);
            // Init Variable
            var_name = "api_manager," + var_name;
            List<object> var_temp = new List<object>(var_value);
            var_temp.Insert(0, super.api_manager);
            // Init ItemMultiChain
            ItemMultiChain item = new ItemMultiChain
            {
                checkpoint = Checkpoint,
                IDPlayerCheck = idPlayer,
                names = var_name,
                values = var_temp.ToArray()
            };
            QueueMultiChain.Enqueue(item);
            Console.WriteLine("Add multi chain CheckPoint=" + Checkpoint.ToString());
            CheckMultiChain();
        }
        public bool CheckItemInListChain(int ID)
        {
            for (int i = 0; i < ListChainNow.Count;i++ )
            {
                if (ListChainNow[i].ID == ID)
                    return false;
            }
            return true;
        }
        
        public bool CheckCanAddChain(int Speed)
        {
            if (ListChainNow.Count == 0)
                return true;
            if (ListChainNow.Last().Speed == 1 && Speed > 1)         
                return true;           
            if (ListChainNow.Last().Speed > 1 && Speed >= ListChainNow.Last().Speed)           
                return true;
            return false;
            
        }

        public void ExcuteChain()
        {
            if (ListChainNow.Count == 0)
                return;
            
            isActiveChain = true;
            isExcuting = true;
            while (ListChainNow.Count > 0)
            {
                ItemChain item = ListChainNow.Last();
                if (isActive(item))
                {
                    if (item.ScriptExcute.Equals(""))
                        item.ScriptExcute = super.CScriptDB.GetScript(item.CardType_ID).Register_Script;

                    super.engine.SetVariable(new string[] { "dondangky" }, new DonDangKi(super.EffectTurnManager, item.ID));
                    super.EffectTurnManager.ActiveWithScript(item.ScriptExcute, super.engine);
                }
                ListChainNow.Remove(item);
                Thread.Sleep(500);
            }    
            Init();            
            CheckMultiChain();
            
        }

        public void CheckMultiChain()
        {
            if (isExcuting)
            {
                Console.WriteLine("Co chain khac dang active");
                return;
            }
            if(QueueMultiChain.Count > 0)
            {
                ItemMultiChain item = QueueMultiChain.Dequeue();
                List<YCheckPoint> checkpoint = new List<YCheckPoint> { item.checkpoint };
                super.ExEffectManager.CheckPointNow = item.checkpoint;
                super.Check_EffectExcute(checkpoint, item.IDPlayerCheck, item.names, item.values);
            }

        }

        private bool isActive(ItemChain item)
        {

            SPlayer player = super.GetPlayerOwner(item.ID);
            SCard card = player.LayCardInAll(item.ID);
            bool check = false;
                switch (card.MyYBaseCard.CardType)
                {
                    case YType.Monster:
                        if (player.Block.DuocPhep_ActiveMonster)
                            check = true;
                        break;
                    case YType.Spell:
                        if (player.Block.DuocPhep_ActiveSpell)
                            check = true;
                        break;
                    case YType.Trap:
                        if (player.Block.DuocPhep_ActiveTrap)
                            check = true;
                        break;
                }
                return check;
        }
        public List<ItemChain> GetListChainNow()
        {
            return ListChainNow;
        }
        public void NegateCardInChain(int IDCard)
        {
            for (int i = 0; i < ListChainNow.Count;i++ )
            {
                if (ListChainNow[i].ID == IDCard)
                {
                    ListChainNow.RemoveAt(i);
                    return;
                }
            }
        }
        public int NegateCardBeforeInChain(int IdCardActive)
        {
            ItemChain active = GetItem(IdCardActive);
            int index = ListChainNow.IndexOf(active);
            if (active == null || index == 0)
                return -1;
            ItemChain Before = ListChainNow[index - 1];
            if (Before != null)
            {
                ListChainNow.Remove(Before);
                Console.WriteLine("----Negate Card ID = " + Before.ID);
                return Before.ID;
            }
            return -1;
        }
        ItemChain GetItem(int ID)
        {
            foreach (ItemChain i in ListChainNow)
            {
                if (i.ID == ID)
                    return i;
            }
            return null;
        }
        public ItemChain GetLastItem()
        {
            if (ListChainNow.Count > 0)
                return ListChainNow.Last();
            return null;
        }
        

    }
    public struct ItemMultiChain
    {
        public YCheckPoint checkpoint;
        public int IDPlayerCheck;
        public string names;
        public object[] values;
    }
}
